package high.concurrent.mq;

import com.rabbitmq.client.Channel;
import high.concurrent.config.LockCouponRecordMQConfig;
import high.concurrent.model.TasklMessage;
import high.concurrent.service.CouponRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 优惠券监听
 */
@Slf4j
@Component
@RabbitListener(queues = LockCouponRecordMQConfig.QUEUE_NAME)
public class CouponMQListener {

    @Autowired
    private CouponRecordService couponRecordService;
    /**
     * 接收
     * 1. 重复消费幂等性
     * 2. 消费失败重入队次数
     * @param couponRecordMessage 消息内容，如果发送消息是个Object，那body类型就是指定的发送Object即可，能自己转型
     * @param message  消息的信息内容，比如标签，发送内容等， 注意导包org.springframework.amqp.core.Message
     */
    @RabbitHandler
    public void firstAmqpHandler(TasklMessage couponRecordMessage, Message message, Channel channel) throws IOException {

        // 拿到消息标识deliveryTag
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        log.info("接收消息内容: {}", couponRecordMessage.toString());

        try {
            // 校验优惠券是否需要回退
            boolean result = couponRecordService.checkCouponRecordTask(couponRecordMessage);

            if(result){
                // 消息确认
                log.info("消息确认");
                channel.basicAck(deliveryTag, false);
            }else{
                // 消息拒绝， 并重入队列
                log.info("优惠券回退检验失败，重新入队");
                channel.basicNack(deliveryTag, false, true);
            }
        } catch (IOException e) {
            // 消息拒绝， 并重入队列
            log.info("优惠券回退检验异常，重新入队");
            channel.basicNack(deliveryTag, false, true);
        }

    }
}
